﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Zanox.Api.Client.Publisher.V20110301;
using Zanox.Api.Client.Auth.V20110501;

namespace Zanox.Api.Client.Publisher.V20110301
{
    public class PublisherAPI
    {
        protected Zanox.Api.Client.Publisher.V20110301.PublisherService publisherService;

        public PublisherAPI() : this(null) { }

        public PublisherAPI(System.Net.IWebProxy proxy)
        {
            #region zanox Publisher Web Services
            publisherService = new Zanox.Api.Client.Publisher.V20110301.PublisherService();
            publisherService.Proxy = proxy;
            publisherService.EnableDecompression = true;
            publisherService.UserAgent = Constants.UserAgent;
            #endregion
        }

        #region Profiles
        public profileItem GetProfile(sessionType session)
        {
            GetProfileRequest parameters = new GetProfileRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "publisherservice", "getprofile", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);

            GetProfileResponse response = publisherService.GetProfile(parameters);

            if (response == null)
            {
                return null;
            }

            return response.profileItem;
        }

        public profileItem UpdateProfile(sessionType session, profileItem profile)
        {
            UpdateProfileRequest parameters = new UpdateProfileRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "publisherservice", "updateprofile", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);

            profileItem profileToChange = new profileItem();
            profileToChange.id = profile.id;
            profileToChange.idSpecified = true;
            profileToChange.firstName = profile.firstName;
            profileToChange.lastName = profile.lastName;
            profileToChange.company = profile.company;
            profileToChange.country = profile.country;
            profileToChange.city = profile.city;
            profileToChange.zipcode = profile.zipcode;
            profileToChange.street1 = profile.street1;
            profileToChange.street2 = profile.street2;

            profileToChange.fax = profile.fax;
            profileToChange.phone = profile.phone;
            profileToChange.mobile = profile.mobile;

            parameters.profileItem = profileToChange;

            UpdateProfileResponse response = publisherService.UpdateProfile(parameters);

            if (response == null)
            {
                return null;
            }

            return response.profileItem;
        }

        #endregion

        #region Adspaces
        public adspaceItem GetAdspace(sessionType session, int adspaceId)
        {
            GetAdspaceRequest parameters = new GetAdspaceRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "publisherservice", "getadspace", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);
            parameters.adspaceId = adspaceId;

            GetAdspaceResponse response = publisherService.GetAdspace(parameters);

            if (response == null)
            {
                return null;
            }

            if (response.adspaceItem == null)
            {
                return null;
            }

            return response.adspaceItem;
        }

        public List<adspaceItem> GetAdspaces(sessionType session, int items, int page, out int total)
        {
            GetAdspacesRequest parameters = new GetAdspacesRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "publisherservice", "getadspaces", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);

            parameters.items = items;
            parameters.itemsSpecified = true;

            parameters.page = page;
            parameters.pageSpecified = true;

            GetAdspacesResponse response = publisherService.GetAdspaces(parameters);

            if (response == null)
            {
                total = 0;
                return null;
            }

            if (response.adspaceItems == null)
            {
                total = 0;
                return null;
            }
            total = (int)response.total;
            return response.adspaceItems.ToList<adspaceItem>();
        }

        public adspaceItem CreateAdspace(sessionType session, adspaceItem adspace)
        {
            CreateAdspaceRequest parameters = new CreateAdspaceRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "publisherservice", "createadspace", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);

            parameters.adspaceItem = adspace;

            CreateAdspaceResponse response = publisherService.CreateAdspace(parameters);
            if (response == null)
            {
                return null;
            }

            return response.adspaceItem;
        }

        public adspaceItem UpdateAdspace(sessionType session, adspaceItem adspace)
        {
            UpdateAdspaceRequest parameters = new UpdateAdspaceRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "publisherservice", "updateadspace", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);

            parameters.adspaceItem = adspace;

            UpdateAdspaceResponse response = publisherService.UpdateAdspace(parameters);
            if (response == null)
            {
                return null;
            }

            return response.adspaceItem;
        }

        public int DeleteAdspace(sessionType session, int adspaceId)
        {
            DeleteAdspaceRequest parameters = new DeleteAdspaceRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "publisherservice", "deleteadspace", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);

            parameters.adspaceId = adspaceId;

            DeleteAdspaceResponse response = publisherService.DeleteAdspace(parameters);

            if (response == null)
            {
                return 0;
            }

            return response.count;
        }

        #endregion

        #region Programs
        /// <summary>
        /// Returns a program by Id
        /// </summary>
        public programItem GetProgram(sessionType session, int programId)
        {

            GetProgramRequest parameters = new GetProgramRequest();
            parameters.connectId = session.connectId;
            parameters.programId = programId;

            GetProgramResponse response = publisherService.GetProgram(parameters);
            if (response == null)
            {
                return null;
            }
            return response.programItem;
        }

        /// <summary>
        /// Search all programs
        /// </summary>
        public List<programItem> SearchPrograms(sessionType session, string query, string region, bool hasProducts, int? categoryId, DateTime? startDate, partnerShipEnum? partnerShip, int page, int items, out int total)
        {
            List<programItem> result = new List<programItem>();

            SearchProgramsRequest parameters = new SearchProgramsRequest();
            parameters.connectId = session.connectId;

            parameters.query = query;
            parameters.region = region;

            if (startDate.HasValue)
            {
                parameters.startDate = startDate.Value;
                parameters.startDateSpecified = true;
            }

            if (partnerShip.HasValue)
            {
                parameters.partnerShip = partnerShip.Value;
                parameters.partnerShipSpecified = true;
            }

            if (hasProducts)
            {
                parameters.hasProducts = hasProducts;
                parameters.hasProductsSpecified = true;
            }

            if (categoryId.HasValue)
            {
                parameters.categoryId = categoryId.Value;
                parameters.categoryIdSpecified = true;
            }

            parameters.page = page;
            parameters.pageSpecified = true;
            parameters.items = items;
            parameters.itemsSpecified = true;

            SearchProgramsResponse response = publisherService.SearchPrograms(parameters);
            if (response == null)
            {
                total = 0;
                return null;
            }

            if (response.programItems == null)
            {
                total = 0;
                return null;
            }

            total = (int)response.total;
            return response.programItems.ToList<programItem>();
        }

        public List<subStringIdentifierType> GetProgramCategories(sessionType session)
        {
            GetProgramCategoriesRequest parameters = new GetProgramCategoriesRequest();
            parameters.connectId = session.connectId;

            GetProgramCategoriesResponse response = publisherService.GetProgramCategories(parameters);
            if (response == null)
            {
                return null;
            }

            if (response == null)
            {
                return null;
            }

            if (response.categories == null)
            {
                return null;
            }

            return response.categories.ToList<subStringIdentifierType>();
        }
        #endregion

        #region ProgramApplication
        /// <summary>
        /// Apply to Program with an AdSpace. Returns new programApplication
        /// </summary>
        public programApplicationItem CreateProgramApplication(sessionType session, int adspaceId, int programId, string comment)
        {
            CreateProgramApplicationRequest parameters = new CreateProgramApplicationRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "publisherservice", "createprogramapplication", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);


            parameters.adspaceId = adspaceId;
            parameters.programId = programId;
            parameters.publisherComment = comment;

            CreateProgramApplicationResponse response = publisherService.CreateProgramApplication(parameters);

            if (response == null)
            {
                return null;
            }

            if (response.programApplicationItem == null)
            {
                return null;
            }
            return response.programApplicationItem;
        }

        /// <summary>
        /// Returns programs applied to an Adspace
        /// </summary>
        public List<programApplicationItem> GetProgramApplications(sessionType session, int? adspaceId, int? programId, programApplicationStatusEnum? status, int items, int page, out int total)
        {
            GetProgramApplicationsRequest parameters = new GetProgramApplicationsRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "publisherservice", "getprogramapplications", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);

            if (adspaceId.HasValue)
            {
                parameters.adspaceId = adspaceId.Value;
                parameters.adspaceIdSpecified = true;
            }

            if (programId.HasValue)
            {
                parameters.programId = programId.Value;
                parameters.programIdSpecified = true;
            }

            if (status.HasValue)
            {
                parameters.status = status.Value;
                parameters.statusSpecified = true;
            }

            parameters.page = page;
            parameters.pageSpecified = true;

            parameters.items = items;
            parameters.itemsSpecified = true;

            GetProgramApplicationsResponse response = publisherService.GetProgramApplications(parameters);

            if (response == null)
            {
                total = 0;
                return null;
            }

            if (response.programApplicationItems == null)
            {
                total = 0;
                return null;
            }
            total = (int)response.total;
            return response.programApplicationItems.ToList<programApplicationItem>();
        }

        /// <summary>
        /// Cancels existing ProgrammeApplication. Returns number of cancelled ProgramApplications (should be 1).
        /// </summary>
        public int DeleteProgramApplication(sessionType session, int adspaceId, int programId)
        {
            DeleteProgramApplicationRequest parameters = new DeleteProgramApplicationRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "publisherservice", "deleteprogramapplication", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);

            parameters.adspaceId = adspaceId;
            parameters.programId = programId;            

            DeleteProgramApplicationResponse response = publisherService.DeleteProgramApplication(parameters);

            if (response == null)
            {
                return 0;
            }
            
            return response.count;
        }
        #endregion

        #region Admedia
        public admediumItem GetAdmedium(sessionType session, int admediumId, int? adspaceId)
        {
            GetAdmediumRequest parameters = new GetAdmediumRequest();
            parameters.connectId = session.connectId;
            parameters.admediumId = admediumId;

            if (adspaceId.HasValue)
            {
                parameters.adspaceId = adspaceId.Value;
                parameters.adspaceIdSpecified = true;
            }

            GetAdmediumResponse response = publisherService.GetAdmedium(parameters);
            if (response == null)
            {
                return null;
            }
            return response.admediumItem;
        }

        public admediumItem GetAdmedium(sessionType session, string trackingLink, int? adspaceId)
        {
            GetAdmediumRequest parameters = new GetAdmediumRequest();
            parameters.connectId = session.connectId;
            parameters.trackingLink = trackingLink;

            if (adspaceId.HasValue)
            {
                parameters.adspaceId = adspaceId.Value;
                parameters.adspaceIdSpecified = true;
            }

            GetAdmediumResponse response = publisherService.GetAdmedium(parameters);
            if (response == null)
            {
                return null;
            }
            return response.admediumItem;
        }

        public List<admediumItem> GetAdmedia(sessionType session, int? programId, int? adspaceId, int? categoryId, admediaTypeEnum? admediaType, int? format, partnerShipEnum? partnerShip, admediaPurposeEnum? admediaPurpose, string region, int page, int items, out int total)
        {
            List<admediumItem> result = new List<admediumItem>();

            GetAdmediaRequest parameters = new GetAdmediaRequest();
            parameters.connectId = session.connectId;

            if (programId.HasValue)
            {
                parameters.programId = programId.Value;
                parameters.programIdSpecified = true;
            }
            if (adspaceId.HasValue)
            {
                parameters.adspaceId = adspaceId.Value;
                parameters.adspaceIdSpecified = true;
            }

            if (categoryId.HasValue)
            {
                parameters.categoryId = categoryId.Value;
                parameters.categoryIdSpecified = true;
            }

            if (format.HasValue)
            {
                parameters.format = format.Value;
                parameters.formatSpecified = true;
            }

            if (admediaType.HasValue)
            {
                parameters.admediumType = admediaType.Value;
                parameters.admediumTypeSpecified = true;
            }

            if (partnerShip.HasValue)
            {
                parameters.partnerShip = partnerShip.Value;
                parameters.partnerShipSpecified = true;
            }

            if (admediaPurpose.HasValue)
            {
                parameters.purpose = admediaPurpose.Value;
                parameters.purposeSpecified = true;
            }

            if (!string.IsNullOrEmpty(region))
            {
                parameters.region = region;
            }

            parameters.items = items;
            parameters.itemsSpecified = true;

            parameters.page = page;
            parameters.pageSpecified = true;

            GetAdmediaResponse response = publisherService.GetAdmedia(parameters);
            if (response == null)
            {
                total = 0;
                return null;
            }

            if (response.admediumItems == null)
            {
                total = 0;
                return null;
            }

            total = (int)response.total;
            return response.admediumItems.ToList<admediumItem>();
        }

        public IList<subStringIdentifierType> GetAdmediumCategories(sessionType session, int programId)
        {
            List<admediumItem> result = new List<admediumItem>();

            GetAdmediumCategoriesRequest parameters = new GetAdmediumCategoriesRequest();
            parameters.connectId = session.connectId;
            parameters.programId = programId;

            GetAdmediumCategoriesResponse response = publisherService.GetAdmediumCategories(parameters);
            if (response == null)
            {
                return null;
            }

            return response.categories;
        }
        #endregion

        #region Products
        public productItem GetProduct(sessionType session, string productId, int? adspaceId)
        {
            GetProductRequest parameters = new GetProductRequest();

            parameters.connectId = session.connectId;
            parameters.zupId = productId;

            if (adspaceId.HasValue)
            {
                parameters.adspaceId = adspaceId.Value;
                parameters.adspaceIdSpecified = true;
            }

            GetProductResponse response = publisherService.GetProduct(parameters);
            if (response == null)
            {
                return null;
            }
            return response.productItem;
        }

        public IList<productItem> SearchProducts(sessionType session, int page, int items, string query, searchTypeEnum? searchType, string region, int[] programIds, int? categoryId, int? adSpaceId, int? minPrice, int? maxPrice, bool? hasImage, out int total)
        {
            SearchProductsRequest parameters = new SearchProductsRequest();
            parameters.connectId = session.connectId;
            parameters.query = query;

            //todo: validate regioncode
            parameters.region = region;

            parameters.programId = programIds;


            if (searchType.HasValue)
            {
                parameters.searchType = searchType.Value;
                parameters.searchTypeSpecified = true;
            }

            if (minPrice.HasValue)
            {
                parameters.minPrice = minPrice.Value;
                parameters.minPriceSpecified = true;
            }

            if (maxPrice.HasValue)
            {
                parameters.maxPrice = maxPrice.Value;
                parameters.maxPriceSpecified = true;
            }

            if (categoryId.HasValue)
            {
                parameters.categoryId = categoryId.Value;
                parameters.categoryIdSpecified = true;
            }

            if (adSpaceId.HasValue)
            {
                parameters.adspaceId = adSpaceId.Value;
                parameters.adspaceIdSpecified = true;
            }

            if (hasImage.HasValue)
            {
                parameters.hasImages = hasImage.Value;
                parameters.hasImagesSpecified = true;
            }

            // paging
            parameters.page = page;
            parameters.pageSpecified = true;

            parameters.items = items;
            parameters.itemsSpecified = true;

            SearchProductsResponse response = publisherService.SearchProducts(parameters);

            if (response == null)
            {
                total = 0;
                return null;
            }

            if (response.productItems == null)
            {
                total = 0;
                return null;
            }

            total = (int)response.total;
            return response.productItems.ToList<productItem>();
        }

        public IList<productCategoryType> GetProductCategories(sessionType session, string region, int? rootCategory, bool? includeChilds)
        {
            GetProductCategoriesRequest parameters = new GetProductCategoriesRequest();
            parameters.connectId = session.connectId;
            parameters.region = region;

            if (rootCategory.HasValue)
            {
                parameters.rootCategory = rootCategory.Value;
                parameters.rootCategorySpecified = true;
            }

            if (includeChilds.HasValue)
            {
                parameters.includeChilds = includeChilds.Value;
                parameters.includeChildsSpecified = true;
            }

            GetProductCategoriesResponse response = publisherService.GetProductCategories(parameters);
            if (response == null)
            {
                return null;
            }

            if (response.categories == null)
            {
                return null;
            }

            return response.categories.ToList<productCategoryType>();
        }
        #endregion

        #region Reports
        public saleItem GetSale(sessionType session, string saleId)
        {
            GetSaleRequest parameters = new GetSaleRequest();
            DateTime timeStamp = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(timeStamp, session.secretKey, "publisherservice", "getsale", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(timeStamp);

            parameters.saleId = saleId;

            GetSaleResponse response = publisherService.GetSale(parameters);

            if (response == null)
            {
                return null;
            }

            return response.saleItem;
        }

        public leadItem GetLead(sessionType session, string leadId)
        {
            GetLeadRequest parameters = new GetLeadRequest();
            DateTime timeStamp = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(timeStamp, session.secretKey, "publisherservice", "getlead", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(timeStamp);

            parameters.leadId = leadId;

            GetLeadResponse response = publisherService.GetLead(parameters);

            if (response == null)
            {
                return null;
            }

            return response.leadItem;
        }

        public IList<saleItem> GetSales(sessionType session, DateTime date, dateTypeEnum dateType, int? adSpaceId, int? programId, reviewStateEnum? reviewState, int items, int page, out int total)
        {
            GetSalesRequest parameters = new GetSalesRequest();

            // authentification & authorization
            DateTime timeStamp = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(timeStamp, session.secretKey, "publisherservice", "getsales", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(timeStamp);

            if (adSpaceId.HasValue)
            {
                parameters.adspaceId = adSpaceId.Value;
                parameters.adspaceIdSpecified = true;
            }

            if (programId.HasValue)
            {
                parameters.programId = programId.Value;
                parameters.programIdSpecified = true;
            }

            if (reviewState.HasValue)
            {
                parameters.reviewState = reviewState.Value;
                parameters.reviewStateSpecified = true;
            }

            parameters.date = date;
            parameters.dateType = dateType;

            parameters.items = items;
            parameters.itemsSpecified = true;

            parameters.page = page;
            parameters.pageSpecified = true;

            GetSalesResponse response = publisherService.GetSales(parameters);

            if (response == null)
            {
                total = 0;
                return null;
            }

            if (response.saleItems == null)
            {
                total = 0;
                return null;
            }

            total = (int)response.total;
            return response.saleItems.ToList<saleItem>();
        }

        public IList<leadItem> GetLeads(sessionType session, DateTime date, dateTypeEnum dateType, int? adSpaceId, int? programId, reviewStateEnum? reviewState, int items, int page, out int total)
        {
            GetLeadsRequest parameters = new GetLeadsRequest();

            // authentification & authorization           
            DateTime timeStamp = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(timeStamp, session.secretKey, "publisherservice", "getleads", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(timeStamp);

            if (adSpaceId.HasValue)
            {
                parameters.adspaceId = adSpaceId.Value;
                parameters.adspaceIdSpecified = true;
            }

            if (programId.HasValue)
            {
                parameters.programId = programId.Value;
                parameters.programIdSpecified = true;
            }

            if (reviewState.HasValue)
            {
                parameters.reviewState = reviewState.Value;
                parameters.reviewStateSpecified = true;
            }

            parameters.date = date;
            parameters.dateType = dateType;

            parameters.items = items;
            parameters.itemsSpecified = true;

            parameters.page = page;
            parameters.pageSpecified = true;

            GetLeadsResponse response = publisherService.GetLeads(parameters);

            if (response == null)
            {
                total = 0;
                return null;
            }

            if (response.leadItems == null)
            {
                total = 0;
                return null;
            }

            total = (int)response.total;
            return response.leadItems.ToList<leadItem>();
        }

        public IList<reportItem> GetReportBasic(sessionType session, DateTime fromDate, DateTime toDate, string currency, groupByEnum[] groupBy, int? adspaceId, int? programId, int? admediumId, reviewStateEnum? reviewState)
        {
            GetReportBasicRequest parameters = new GetReportBasicRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.timestamp = Signature.GetZDateTime(now);
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "publisherservice", "getreportbasic", parameters.nonce);

            parameters.groupBy = groupBy;
            parameters.fromDate = fromDate;
            parameters.toDate = toDate;
            parameters.currency = currency;

            if (programId.HasValue)
            {
                parameters.programId = programId.Value;
                parameters.programIdSpecified = true;
            }

            if (reviewState.HasValue)
            {
                parameters.reviewState = reviewState.Value;
                parameters.reviewStateSpecified = true;
            }

            if (adspaceId.HasValue)
            {
                parameters.adspaceId = adspaceId.Value;
                parameters.adspaceIdSpecified = true;
            }

            if (admediumId.HasValue)
            {
                parameters.admediumId = admediumId.Value;
                parameters.admediumIdSpecified = true;
            }

            GetReportBasicResponse response = publisherService.GetReportBasic(parameters);
            if (response == null)
            {
                return null;
            }

            if (response.reportItems == null)
            {
                return null;
            }

            return response.reportItems.ToList<reportItem>();
        }
        #endregion

        #region Payments
        public paymentItem GetPayment(sessionType session, string paymentId)
        {
            GetPaymentRequest parameters = new GetPaymentRequest();

            DateTime timeStamp = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(timeStamp, session.secretKey, "publisherservice", "getpayment", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(timeStamp);

            parameters.paymentId = paymentId;

            GetPaymentResponse response = publisherService.GetPayment(parameters);

            if (response == null)
            {
                return null;
            }

            return response.paymentItem;
        }

        public IList<paymentItem> GetPayments(sessionType session, int items, int page, out int total)
        {
            GetPaymentsRequest parameters = new GetPaymentsRequest();

            DateTime timeStamp = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(timeStamp, session.secretKey, "publisherservice", "getpayments", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(timeStamp);

            parameters.items = items;
            parameters.itemsSpecified = true;

            parameters.page = page;
            parameters.pageSpecified = true;

            GetPaymentsResponse response = publisherService.GetPayments(parameters);

            if (response == null)
            {
                total = 0;
                return null;
            }

            if (response.paymentItems == null)
            {
                total = 0;
                return null;
            }

            total = (int)response.total;
            return response.paymentItems.ToList<paymentItem>();
        }
        #endregion

        #region Balances
        public balanceItem GetBalance(sessionType session, string currency)
        {
            GetBalanceRequest parameters = new GetBalanceRequest();

            DateTime timeStamp = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(timeStamp, session.secretKey, "publisherservice", "getbalance", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(timeStamp);

            parameters.currency = currency;

            GetBalanceResponse response = publisherService.GetBalance(parameters);

            if (response == null)
            {
                return null;
            }

            return response.balanceItem;
        }

        public IList<balanceItem> GetBalances(sessionType session, int items, int page, out int total)
        {
            GetBalancesRequest parameters = new GetBalancesRequest();

            DateTime timeStamp = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(timeStamp, session.secretKey, "publisherservice", "getbalances", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(timeStamp);

            parameters.items = items;
            parameters.itemsSpecified = true;
            parameters.page = page;
            parameters.pageSpecified = true;

            GetBalancesResponse response = publisherService.GetBalances(parameters);

            if (response == null)
            {
                total = 0;
                return null;
            }

            if (response.balanceItems == null)
            {
                total = 0;
                return null;
            }

            total = (int)response.total;
            return response.balanceItems.ToList<balanceItem>();
        }
        #endregion

        #region BankAccounts
        public bankAccountItem GetBankAccount(sessionType session, string bankAccountId)
        {
            GetBankAccountRequest parameters = new GetBankAccountRequest();

            DateTime timeStamp = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(timeStamp, session.secretKey, "publisherservice", "getbankaccount", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(timeStamp);
            parameters.bankAccountId = bankAccountId;

            GetBankAccountResponse response = publisherService.GetBankAccount(parameters);

            if (response == null)
            {
                return null;
            }

            return response.bankAccountItem;
        }

        public IList<bankAccountItem> GetBankAccounts(sessionType session, int items, int page, out int total)
        {
            GetBankAccountsRequest parameters = new GetBankAccountsRequest();

            DateTime timeStamp = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(timeStamp, session.secretKey, "publisherservice", "getbankaccounts", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(timeStamp);

            parameters.items = items;
            parameters.itemsSpecified = true;
            parameters.page = page;
            parameters.pageSpecified = true;

            GetBankAccountsResponse response = publisherService.GetBankAccounts(parameters);

            if (response == null)
            {
                total = 0;
                return null;
            }

            if (response.bankAccountItems == null)
            {
                total = 0;
                return null;
            }

            total = (int)response.total;
            return response.bankAccountItems.ToList<bankAccountItem>();
        }
        #endregion

        #region Applications
        public applicationItem GetApplication(sessionType session, string applicationId)
        {
            GetApplicationRequest parameters = new GetApplicationRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "publisherservice", "getapplication", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);

            parameters.applicationId = applicationId;

            GetApplicationResponse response = publisherService.GetApplication(parameters);

            if (response == null)
            {
                return null;
            }

            return response.applicationItem;
        }

        public IList<applicationItem> GetApplications(sessionType session, applicationTypeEnum? applicationType, roleTypeEnum? role, string name, int items, int page, out int total)
        {
            GetApplicationsRequest parameters = new GetApplicationsRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "mediaslotservice", "getapplications", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);

            if (applicationType.HasValue)
            {
                parameters.applicationType = applicationType.Value;
                parameters.applicationTypeSpecified = true;
            }

            if (role.HasValue)
            {
                parameters.role = role.Value;
                parameters.roleSpecified = true;
            }

            if (!string.IsNullOrWhiteSpace(name))
            {
                parameters.name = name;
                //parameters.nameSpecified = name;     
            }

            parameters.items = items;
            parameters.itemsSpecified = true;

            parameters.page = page;
            parameters.pageSpecified = true;


            GetApplicationsResponse response = publisherService.GetApplications(parameters);

            if (response == null)
            {
                total = 0;
                return null;
            }

            if (response.applicationItems == null)
            {
                total = 0;
                return null;
            }

            var applications = response.applicationItems.ToList<applicationItem>();
            total = (int)response.total;
            return applications;
        }

        public applicationItem CreateApplication()
        {
            throw new NotImplementedException();
        }

        public applicationItem UpdateApplication()
        {
            throw new NotImplementedException();
        }

        public void DeleteApplication()
        {
            throw new NotImplementedException();
        }
        #endregion

        #region MediaSlots
        public mediaSlotItem GetMediaSlot(sessionType session, string mediaslotId)
        {
            GetMediaSlotRequest parameters = new GetMediaSlotRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "publisherservice", "getmediaslot", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);
            parameters.mediaSlotId = mediaslotId;

            GetMediaSlotResponse response = publisherService.GetMediaSlot(parameters);

            if (response == null)
            {
                return null;
            }

            return response.mediaSlotItem;
        }

        public IList<mediaSlotItem> GetMediaSlots(sessionType session, int? adspaceId, int? width, int? height, int? format, int items, int page, out int total)
        {
            GetMediaSlotsRequest parameters = new GetMediaSlotsRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "publisherservice", "getmediaslots", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);

            parameters.items = items;
            parameters.itemsSpecified = true;

            parameters.page = page;
            parameters.adspaceIdSpecified = true;

            if (adspaceId.HasValue)
            {
                parameters.adspaceId = adspaceId.Value;
                parameters.adspaceIdSpecified = true;
            }

            parameters.size = new sizeType();
            if (height.HasValue)
            {
                parameters.size.height = height.Value;
                parameters.size.heightSpecified = true;
            }

            if (width.HasValue)
            {
                parameters.size.width = width.Value;
                parameters.size.widthSpecified = true;
            }

            if (format.HasValue)
            {
                parameters.size.format = new subStringIdentifierType();
                parameters.size.format.id = format.Value;
            }

            GetMediaSlotsResponse response = publisherService.GetMediaSlots(parameters);

            if (response == null)
            {
                total = 0;
                return null;
            }

            if (response.mediaSlotItems == null)
            {
                total = 0;
                return null;
            }
            total = (int)response.total;
            return response.mediaSlotItems.ToList<mediaSlotItem>();
        }

        public mediaSlotItem CreateMediaSlot(sessionType session, mediaSlotItem mediaSlot)
        {
            CreateMediaSlotRequest parameters = new CreateMediaSlotRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "publisherservice", "createmediaslot", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);

            // todo: validate mediaSlot            
            parameters.mediaSlotItem = mediaSlot;

            CreateMediaSlotResponse response = publisherService.CreateMediaSlot(parameters);

            if (response == null)
            {
                return null;
            }

            return response.mediaSlotItem;
        }

        public mediaSlotItem UpdateMediaSlot(sessionType session, mediaSlotItem mediaSlot)
        {
            UpdateMediaSlotRequest parameters = new UpdateMediaSlotRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "publisherservice", "updatemediaslot", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);

            // todo: validate mediaSlot            
            parameters.mediaSlotItem = mediaSlot;

            UpdateMediaSlotResponse response = publisherService.UpdateMediaSlot(parameters);

            if (response == null)
            {
                return null;
            }
            return response.mediaSlotItem;
        }

        public int DeleteMediaSlot(sessionType session, string mediaSlotId)
        {
            DeleteMediaSlotRequest parameters = new DeleteMediaSlotRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "publisherservice", "updatemediaslot", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);

            parameters.mediaSlotId = mediaSlotId;

            DeleteMediaSlotResponse response = publisherService.DeleteMediaSlot(parameters);

            if (response == null)
            {
                return 0;
            }
            return response.count;
        }
        #endregion

        #region Settings
        public settingItem GetSetting(sessionType session, string mediaSlotId, string applicationId, string key)
        {
            GetSettingRequest parameters = new GetSettingRequest();
            parameters.connectId = session.connectId;

            parameters.mediaSlotId = mediaSlotId;
            parameters.applicationId = applicationId;
            parameters.key = key;

            GetSettingResponse response = publisherService.GetSetting(parameters);

            if (response == null)
            {
                return null;
            }

            return response.settingItem;
        }

        public IList<settingItem> GetSettings(sessionType session, string mediaSlotId, string applicationId, int items, int page, out int total)
        {
            GetSettingsRequest parameters = new GetSettingsRequest();
            parameters.connectId = session.connectId;

            parameters.mediaSlotId = mediaSlotId;
            parameters.applicationId = applicationId;

            parameters.items = items;
            parameters.itemsSpecified = true;
            parameters.page = page;
            parameters.pageSpecified = true;

            GetSettingsResponse response = publisherService.GetSettings(parameters);

            if (response == null)
            {
                total = 0;
                return null;
            }

            if (response.settingItems == null)
            {
                total = 0;
                return null;
            }

            total = (int)response.total;
            return response.settingItems.ToList<settingItem>();
        }

        /// <summary>
        /// Called by the developer to add a setting to the list of settings of his application.
        /// </summary>
        /// <param name="session"></param>
        /// <param name="setting"></param>
        /// <returns></returns>
        public settingItem CreateSetting(sessionType session, settingItem setting)
        {
            CreateSettingRequest parameters = new CreateSettingRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "publisherservice", "createsetting", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);

            parameters.settingItem = setting;

            CreateSettingResponse response = publisherService.CreateSetting(parameters);

            if (response == null)
            {
                return null;
            }

            return response.settingItem;
        }

        /// <summary>
        /// Called by the developer to update a setting of his application.
        /// </summary>
        /// <param name="session"></param>
        /// <param name="setting"></param>
        /// <returns></returns>
        public settingItem UpdateSetting(sessionType session, settingItem setting)
        {
            UpdateSettingRequest parameters = new UpdateSettingRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "publisherservice", "updatesetting", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);

            // todo: validate settingItem            
            parameters.settingItem = setting;

            UpdateSettingResponse response = publisherService.UpdateSetting(parameters);

            if (response == null)
            {
                return null;
            }
            return response.settingItem;
        }

        /// <summary>
        /// Called by the developer to redurce the list of settings of his application.
        /// </summary>
        /// <param name="session"></param>
        /// <param name="mediaSlotId"></param>
        /// <param name="applicationId"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public int DeleteSetting(sessionType session, string mediaSlotId, string applicationId, string key)
        {
            DeleteSettingRequest parameters = new DeleteSettingRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "publisherservice", "deletesetting", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);

            parameters.key = key;
            parameters.applicationId = applicationId;

            DeleteSettingResponse response = publisherService.DeleteSetting(parameters);

            if (response == null)
            {
                return 0;
            }
            return response.count;
        }
        #endregion

        #region Incentives
        public incentiveItem GetIncentive(sessionType session, string incentiveId, int? adspaceId)
        {
            GetIncentiveRequest parameters = new GetIncentiveRequest();
            parameters.connectId = session.connectId;

            parameters.incentiveId = incentiveId;

            if (adspaceId.HasValue)
            {
                parameters.adspaceId = adspaceId.Value;
                parameters.adspaceIdSpecified = true;
            }

            GetIncentiveResponse response = publisherService.GetIncentive(parameters);

            if (response == null)
            {
                return null;
            }

            return response.incentiveItem;
        }

        /// <summary>
        /// Get Incentives
        /// </summary>
        /// <param name="session"></param>
        /// <param name="region"></param>
        /// <param name="incentiveType"></param>
        /// <param name="programId"></param>
        /// <param name="adspaceId"></param>
        /// <param name="page"></param>
        /// <param name="items">supports pageSize of 2000 items</param>
        /// <param name="total"></param>
        /// <returns></returns>        
        public IList<incentiveItem> SearchIncentives(sessionType session, string region, incentiveTypeEnum? incentiveType, int? programId, int? adspaceId, int page, int items, out int total)
        {
            SearchIncentivesRequest parameters = new SearchIncentivesRequest();
            parameters.connectId = session.connectId;

            if (adspaceId.HasValue)
            {
                parameters.adspaceId = adspaceId.Value;
                parameters.adspaceIdSpecified = true;
            }

            if (programId.HasValue)
            {
                parameters.programId = programId.Value;
                parameters.programIdSpecified = true;
            }

            if (incentiveType.HasValue)
            {
                parameters.incentiveType = incentiveType.Value;
                parameters.incentiveTypeSpecified = true;
            }

            if (!string.IsNullOrEmpty(region))
            {
                parameters.region = region;
            }

            parameters.page = page;
            parameters.pageSpecified = true;
            parameters.items = items;
            parameters.itemsSpecified = true;

            SearchIncentivesResponse response = publisherService.SearchIncentives(parameters);

            if (response == null)
            {
                total = 0;
                return null;
            }

            if (response.incentiveItems == null)
            {
                total = 0;
                return null;
            }

            total = (int)response.total;
            return response.incentiveItems.ToList<incentiveItem>();
        }

        public incentiveItem GetExclusiveIncentive(sessionType session, string incentiveId, int? adspaceId)
        {
            GetExclusiveIncentiveRequest parameters = new GetExclusiveIncentiveRequest();

            DateTime timeStamp = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(timeStamp, session.secretKey, "publisherservice", "getexclusiveincentive", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(timeStamp);

            parameters.incentiveId = incentiveId;

            if (adspaceId.HasValue)
            {
                parameters.adspaceId = adspaceId.Value;
                parameters.adspaceIdSpecified = true;
            }

            GetExclusiveIncentiveResponse response = publisherService.GetExclusiveIncentive(parameters);

            if (response == null)
            {
                return null;
            }

            return response.incentiveItem;
        }

        /// <summary>
        /// Get exclusive Incentives
        /// </summary>
        /// <param name="session"></param>
        /// <param name="region"></param>
        /// <param name="incentiveType"></param>
        /// <param name="programId"></param>
        /// <param name="adspaceId"></param>
        /// <param name="page"></param>
        /// <param name="items">supports pageSize of 2000 items</param>
        /// <param name="total"></param>
        /// <returns></returns>
        public IList<incentiveItem> GetExclusiveIncentives(sessionType session, string region, incentiveTypeEnum? incentiveType, int? programId, int? adspaceId, int page, int items, out int total)
        {
            SearchExclusiveIncentivesRequest parameters = new SearchExclusiveIncentivesRequest();

            DateTime timeStamp = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(timeStamp, session.secretKey, "publisherservice", "searchexclusiveincentives", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(timeStamp);


            if (adspaceId.HasValue)
            {
                parameters.adspaceId = adspaceId.Value;
                parameters.adspaceIdSpecified = true;
            }

            if (programId.HasValue)
            {
                parameters.programId = programId.Value;
                parameters.programIdSpecified = true;
            }

            if (incentiveType.HasValue)
            {
                parameters.incentiveType = incentiveType.Value;
                parameters.incentiveTypeSpecified = true;
            }

            if (!string.IsNullOrEmpty(region))
            {
                parameters.region = region;
            }

            parameters.page = page;
            parameters.pageSpecified = true;
            parameters.items = items;
            parameters.itemsSpecified = true;

            SearchExclusiveIncentivesResponse response = publisherService.SearchExclusiveIncentives(parameters);

            if (response == null)
            {
                total = 0;
                return null;
            }

            if (response.incentiveItems == null)
            {
                total = 0;
                return null;
            }

            total = (int)response.total;
            return response.incentiveItems.ToList<incentiveItem>();
        }
        #endregion

        #region TrackingCategories
        public IList<trackingCategoryItem> GetTrackingCategories(sessionType session, int programId, int adspaceId, int items, int page, out int total)
        {
            GetTrackingCategoriesRequest parameters = new GetTrackingCategoriesRequest();
            DateTime now = DateTime.UtcNow;
            parameters.nonce = Signature.GetNonce();
            parameters.connectId = session.connectId;
            parameters.signature = Signature.SoapSignature(now, session.secretKey, "publisherservice", "gettrackingcategories", parameters.nonce);
            parameters.timestamp = Signature.GetZDateTime(now);

            parameters.adspaceId = adspaceId;
            parameters.programId = programId;

            parameters.page = page;
            parameters.pageSpecified = true;
            parameters.items = items;
            parameters.itemsSpecified = true;

            GetTrackingCategoriesResponse response = publisherService.GetTrackingCategories(parameters);

            if (response == null)
            {
                total = 0;
                return null;
            }

            if (response.trackingCategoryItem == null)
            {
                total = 0;
                return null;
            }

            total = (int)response.total;
            return response.trackingCategoryItem.ToList<trackingCategoryItem>();
        }
        #endregion
    }
}

